#include "OgreGLESRenderTexture.h"
#include "OgreGLESPixelFormat.h"
#include "OgreGLESHardwarePixelBuffer.h"

#include "OgreLogManager.h"
#include "OgreStringConverter.h"
#include "OgreRoot.h"

namespace Ogre
{
	template<> GLESRTTManager* Singleton<GLESRTTManager>::ms_Singleton = 0;
	
	GLESRTTManager::~GLESRTTManager()
	{
	}
	
	MultiRenderTarget* GLESRTTManager::createMultiRenderTarget(const String& name)
	{
		OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
					"MultiRenderTarget can only be used with GL_OES_framebuffer_object extensions",
					"GLESRTTManager::createMultiRenderTarget");
	}
	
	PixelFormat GLESRTTManager::getSupportedAlternative(PixelFormat format)
	{
		if (checkFormat(format))
		{
			return format;
		}
		
		PixelComponentType pct = PixelUtil::getComponentType(format);
		
		switch(pct)
		{
			case PCT_BYTE:
				format = PF_A8R8G8B8;
				break;
			case PCT_SHORT:
				format = PF_SHORT_RGBA;
				break;
			case PCT_FLOAT16:
				format = PF_FLOAT16_RGBA;
				break;
			case PCT_FLOAT32:
				format = PF_FLOAT32_RGBA;
				break;
			case PCT_COUNT:
			default:
				break;
		}
		
		if (checkFormat(format))
			return format;
			
		return PF_A8R8G8B8;
	}
	
	GLESRenderTexture::GLESRenderTexture(const String& name,
										 const GLESSurfaceDesc& target,
										 bool writeGamma,
										 uint fsaa)
		: RenderTexture(target.buffer, target.zoffset)
	{
		mName = name;
		mHwGamma = writeGamma;
		mFSAA = fsaa;
	}
	
	GLESRenderTexture::~GLESRenderTexture()
	{
	}
	
	GLESCopyingRenderTexture::GLESCopyingRenderTexture(GLESCopyingRTTManager* manager,
												const String& name,
												const GLESSurfaceDesc& target,
												bool writeGamma, uint fsaa)
		: GLESRenderTexture(name, target, writeGamma, fsaa)
	{
	}
	
	GLESCopyingRTTManager::GLESCopyingRTTManager()
	{
	}
	
	GLESCopyingRTTManager::~GLESCopyingRTTManager()
	{
	}
	
	RenderTexture* GLESCopyingRTTRanager::createRenderTexture(const String& name,
															  const GLESSurfaceDesc& target,
															  bool writeGamma, uint fsaa)
	{
		return OGRE_NEW GLESCopyingRenderTexture(this, name, target, writeGamma, fsaa);
	}
	
	bool GLESCopyingRTTManager::checkFormat(PixelFormat format)
	{
		return true;
	}
	
	void GLESCopyingRTTManager::bind(RenderTarget* target)
	{
	}
	
	void GLESCopyingRTTManager::unbind(RenderTarget* target)
	{
		GLESSurfaceDesc surface;
		surface.buffer = 0;
		target->getCustomAttribute("TARGET", &surface);
		if (surface.buffer)
		{
			static_cast<GLESTextureBuffer*>(surface.buffer)->copyFromFramebuffer(surface.zoffset);
		}
	}
}
